import { ref, reactive, onMounted, onUnmounted } from 'vue'

// SSE连接管理器 - 全局单例，在应用级别保持连接
class SSEConnectionManager {
  // SSH日志SSE连接
  private sshEventSource: EventSource | null = null
  private sshConnectionStatus = ref<'disconnected' | 'connecting' | 'connected' | 'error'>('disconnected')
  private sshReconnectAttempts = 0
  private readonly maxReconnectAttempts = 5
  private readonly reconnectDelay = 3000
  private sshConnectionTimeout: number | null = null
  
  // 攻击包统计SSE连接
  private packageEventSource: EventSource | null = null
  private packageReconnectAttempts = 0
  private packageConnectionTimeout: number | null = null
  
  // QPS曲线图数据获取（使用HTTP轮询方式，不再使用SSE）
  private qpsPollingInterval: number | null = null
  private qpsReconnectAttempts = 0
  private qpsConnectionStatus = ref<'disconnected' | 'connecting' | 'connected' | 'error'>('disconnected')
  // QPS 时间起点（用于生成 tSec）
  private qpsStartTime: number | null = null
  private readonly qpsPollingIntervalMs = 2000  // 每2秒轮询一次
  // 数据存储
  public readonly sshLogs = ref<string[]>([])
  public readonly packageStats = reactive({
    totalPackages: 0,
    nonDualStackPackages: 0,
    timestamp: '',
    victimTaskId: '',
    attackDurationTime: 0,
    attackDuration: '0秒',
    // 新增：闪聚期时间（秒），对应后端的 flash_mob_time
    flashBobTime: 0
  })
  public readonly qpsData = reactive({
    dualStackQps: [] as Array<{ timestamp: string; qps: number; tSec: number }>,
    nonDualStackQps: [] as Array<{ timestamp: string; qps: number; tSec: number }>,
    maxDataPoints: 60,
    maxQps: 100,
    analysisId: ''
  })
  
  // 状态暴露
  public getSshConnectionStatus() {
    return this.sshConnectionStatus
  }
  
  public getQpsConnectionStatus() {
    return this.qpsConnectionStatus
  }
  
  // 启动所有连接（SSE和HTTP轮询）
  public startAllConnections() {
    console.log('[连接管理器] 启动所有连接...')
    this.connectSSE()
    this.connectPackageStats()
    this.connectQpsChart()  // QPS使用HTTP轮询，不再使用SSE
  }
  
  // 停止所有连接
  public stopAllConnections() {
    console.log('[连接管理器] 停止所有连接...')
    this.disconnectSSE()
    this.disconnectPackageStats()
    this.disconnectQpsChart()
  }
  
  // 连接SSH日志SSE
  private async connectSSE() {
    if (this.sshEventSource && this.sshEventSource.readyState === EventSource.OPEN) {
      console.log('[SSE管理器] SSH日志连接已存在且正常')
      return
    }
    
    if (this.sshEventSource) {
      this.disconnectSSE()
      await new Promise(resolve => setTimeout(resolve, 100))
    }
    
    if (this.sshConnectionTimeout !== null) {
      clearTimeout(this.sshConnectionTimeout)
      this.sshConnectionTimeout = null
    }
    
    this.sshReconnectAttempts = 0
    this.sshConnectionStatus.value = 'connecting'
    
    try {
      const sseUrl = '/api/victim-logs'
      console.log('[SSE管理器] 正在连接SSH日志SSE:', sseUrl)
      
      this.sshEventSource = new EventSource(sseUrl)
      this.sshLogs.value.push(`[${new Date().toLocaleTimeString()}] system: 正在建立SSE连接...`)
      
      this.sshConnectionTimeout = window.setTimeout(() => {
        if (this.sshConnectionStatus.value === 'connecting') {
          console.error('[SSE管理器] SSH日志SSE连接超时')
          this.sshLogs.value.push(`[${new Date().toLocaleTimeString()}] system: SSE连接超时`)
          this.disconnectSSE()
          this.sshConnectionStatus.value = 'error'
          if (this.sshReconnectAttempts < this.maxReconnectAttempts) {
            this.sshReconnectAttempts++
            setTimeout(() => this.connectSSE(), this.reconnectDelay)
          }
        }
      }, 10000)
      
      this.sshEventSource.onopen = () => {
        if (this.sshConnectionTimeout !== null) {
          clearTimeout(this.sshConnectionTimeout)
          this.sshConnectionTimeout = null
        }
        console.log('[SSE管理器] SSH日志SSE连接已建立')
        this.sshConnectionStatus.value = 'connected'
        this.sshReconnectAttempts = 0
        this.sshLogs.value.push(`[${new Date().toLocaleTimeString()}] system: SSE连接已建立`)
      }
      
      this.sshEventSource.onmessage = (event) => {
        try {
          const logData = JSON.parse(event.data)
          let logMessage = ''
          
          if (logData.type === 'connected') {
            logMessage = `[${new Date().toLocaleTimeString()}] system: ${logData.message}`
          } else if (logData.type === 'victim_log') {
            const time = logData.timestamp !== 'N/A' ? 
              new Date(logData.timestamp).toLocaleTimeString() : 
              'N/A'
            logMessage = `[${time}] ${logData.source}: ${logData.message}`
          } else {
            const time = logData.timestamp ? 
              new Date(logData.timestamp).toLocaleTimeString() : 
              new Date().toLocaleTimeString()
            logMessage = `[${time}] ${logData.source || 'system'}: ${logData.message}`
          }
          
          this.sshLogs.value.push(logMessage)
          if (this.sshLogs.value.length > 50) {
            this.sshLogs.value = this.sshLogs.value.slice(-50)
          }
        } catch (error) {
          console.error('[SSE管理器] 解析SSH日志消息失败:', error)
        }
      }
      
      this.sshEventSource.onerror = (error: Event) => {
        if (this.sshConnectionTimeout !== null) {
          clearTimeout(this.sshConnectionTimeout)
          this.sshConnectionTimeout = null
        }
        console.error('[SSE管理器] SSH日志SSE连接错误:', error)
        this.sshConnectionStatus.value = 'error'
        this.sshLogs.value.push(`[${new Date().toLocaleTimeString()}] system: SSE连接错误`)
        
        if (this.sshEventSource && this.sshEventSource.readyState === EventSource.CLOSED) {
          this.disconnectSSE()
          if (this.sshReconnectAttempts < this.maxReconnectAttempts) {
            this.sshReconnectAttempts++
            setTimeout(() => this.connectSSE(), this.reconnectDelay)
          }
        }
      }
    } catch (error) {
      console.error('[SSE管理器] 建立SSH日志SSE连接失败:', error)
      this.sshConnectionStatus.value = 'error'
    }
  }
  
  private disconnectSSE() {
    if (this.sshEventSource) {
      try {
        this.sshEventSource.onopen = null
        this.sshEventSource.onmessage = null
        this.sshEventSource.onerror = null
        this.sshEventSource.close()
      } catch (error) {
        console.error('[SSE管理器] 断开SSH日志SSE连接时出错:', error)
      } finally {
        this.sshEventSource = null
        this.sshConnectionStatus.value = 'disconnected'
      }
    }
    if (this.sshConnectionTimeout !== null) {
      clearTimeout(this.sshConnectionTimeout)
      this.sshConnectionTimeout = null
    }
  }
  
  // 连接攻击包统计SSE
  private async connectPackageStats() {
    if (this.packageEventSource && this.packageEventSource.readyState === EventSource.OPEN) {
      console.log('[SSE管理器] 攻击包统计连接已存在且正常')
      return
    }
    
    if (this.packageEventSource) {
      this.disconnectPackageStats()
      await new Promise(resolve => setTimeout(resolve, 100))
    }
    
    if (this.packageConnectionTimeout !== null) {
      clearTimeout(this.packageConnectionTimeout)
      this.packageConnectionTimeout = null
    }
    
    this.packageReconnectAttempts = 0
    
    try {
      const packageUrl = '/api/attack/package'
      console.log('[SSE管理器] 正在连接攻击包统计SSE:', packageUrl)
      
      this.packageEventSource = new EventSource(packageUrl)
      
      this.packageConnectionTimeout = window.setTimeout(() => {
        if (this.packageEventSource && this.packageEventSource.readyState !== EventSource.OPEN) {
          console.error('[SSE管理器] 攻击包统计SSE连接超时')
          this.disconnectPackageStats()
          if (this.packageReconnectAttempts < this.maxReconnectAttempts) {
            this.packageReconnectAttempts++
            setTimeout(() => this.connectPackageStats(), this.reconnectDelay)
          }
        }
      }, 10000)
      
      this.packageEventSource.onopen = () => {
        if (this.packageConnectionTimeout !== null) {
          clearTimeout(this.packageConnectionTimeout)
          this.packageConnectionTimeout = null
        }
        console.log('[SSE管理器] 攻击包统计SSE连接已建立')
        this.packageReconnectAttempts = 0
      }
      
      this.packageEventSource.onmessage = (event) => {
        try {
          const data = JSON.parse(event.data)
          this.packageStats.timestamp = data.timestamp || ''
          this.packageStats.totalPackages = data.total_packages || 0
          this.packageStats.nonDualStackPackages = data.non_dual_stack_packages || 0
          this.packageStats.victimTaskId = data.victim_task_id || ''
          this.packageStats.attackDurationTime = data.attack_duration_time || 0
          // 新增：接收后端闪聚期时间（秒）
          this.packageStats.flashBobTime = data.flash_mob_time || 0
          
          const duration = Math.floor(this.packageStats.attackDurationTime)
          const minutes = Math.floor(duration / 60)
          const seconds = duration % 60
          this.packageStats.attackDuration = minutes > 0 
            ? `${minutes}分${seconds}秒` 
            : `${seconds}秒`
        } catch (error) {
          console.error('[SSE管理器] 解析攻击包统计数据失败:', error)
        }
      }
      
      this.packageEventSource.onerror = (error) => {
        if (this.packageConnectionTimeout !== null) {
          clearTimeout(this.packageConnectionTimeout)
          this.packageConnectionTimeout = null
        }
        console.error('[SSE管理器] 攻击包统计SSE连接错误:', error)
        
        if (this.packageEventSource && this.packageEventSource.readyState === EventSource.CLOSED) {
          this.disconnectPackageStats()
          if (this.packageReconnectAttempts < this.maxReconnectAttempts) {
            this.packageReconnectAttempts++
            setTimeout(() => this.connectPackageStats(), this.reconnectDelay)
          }
        }
      }
    } catch (error) {
      console.error('[SSE管理器] 建立攻击包统计SSE连接失败:', error)
      if (this.packageConnectionTimeout !== null) {
        clearTimeout(this.packageConnectionTimeout)
        this.packageConnectionTimeout = null
      }
      this.disconnectPackageStats()
      if (this.packageReconnectAttempts < this.maxReconnectAttempts) {
        this.packageReconnectAttempts++
        setTimeout(() => this.connectPackageStats(), this.reconnectDelay)
      }
    }
  }
  
  private disconnectPackageStats() {
    if (this.packageEventSource) {
      try {
        this.packageEventSource.onopen = null
        this.packageEventSource.onmessage = null
        this.packageEventSource.onerror = null
        this.packageEventSource.close()
      } catch (error) {
        console.error('[SSE管理器] 断开攻击包统计SSE连接时出错:', error)
      } finally {
        this.packageEventSource = null
      }
    }
    if (this.packageConnectionTimeout !== null) {
      clearTimeout(this.packageConnectionTimeout)
      this.packageConnectionTimeout = null
    }
  }
  
  // 获取QPS数据（使用HTTP轮询方式）
  private async fetchQpsData() {
    try {
      const qpsUrl = '/api/attack/qps'
      const response = await fetch(qpsUrl, {
        method: 'GET',
        headers: {
          'Accept': 'application/json'
        }
      })
      
      if (!response.ok) {
        throw new Error(`HTTP error! status: ${response.status}`)
      }
      
      const data = await response.json()
      
      // 判断是数组格式（完整数据）还是单个对象格式（兼容旧格式）
      const dataArray = Array.isArray(data) ? data : [data]
      
      if (dataArray.length === 0) {
        // 如果没有数据，保持连接状态但不清空现有数据
        return
      }
      
      // 获取第一个数据点的 analysis_id（所有数据点应该使用相同的 analysis_id）
      this.qpsData.analysisId = dataArray[0].analysis_id || ''
      
      // 解析时间戳并计算相对时间（从第一个数据点开始）
      let firstTimestamp: number | null = null
      
      // 清空旧数据，使用新的完整数据集
      this.qpsData.dualStackQps = []
      this.qpsData.nonDualStackQps = []
      
      dataArray.forEach((item: any) => {
        const timestamp = item.timestamp || new Date().toISOString()
        const currentQps = item.current_qps || 0
        const nonDualStackQps = item.non_dual_stack_qps || 0
        
        // 解析时间戳字符串为时间戳（毫秒）
        let timestampMs: number
        try {
          // 尝试解析 "2025-11-23 14:30:01" 格式
          const dateStr = timestamp.replace(' ', 'T')
          timestampMs = new Date(dateStr).getTime()
          if (isNaN(timestampMs)) {
            // 如果解析失败，使用当前时间
            timestampMs = Date.now()
          }
        } catch {
          timestampMs = Date.now()
        }
        
        // 设置第一个时间戳作为基准时间
        if (firstTimestamp === null) {
          firstTimestamp = timestampMs
          this.qpsStartTime = firstTimestamp
        }
        
        // 计算相对时间（秒），从第一个数据点开始
        const tSec = (timestampMs - firstTimestamp) / 1000
        
        this.qpsData.dualStackQps.push({ timestamp, qps: currentQps, tSec })
        this.qpsData.nonDualStackQps.push({ timestamp, qps: nonDualStackQps, tSec })
      })
      
      // 计算最大QPS值，用于调整Y轴范围
      const allQps = [
        ...this.qpsData.dualStackQps.map(d => d.qps),
        ...this.qpsData.nonDualStackQps.map(d => d.qps)
      ]
      const maxCurrentQps = Math.max(...allQps, 10)
      // 向上取整到最近的50的倍数，并增加20%的留白
      this.qpsData.maxQps = Math.ceil(maxCurrentQps * 1.2 / 50) * 50
      
      // 更新连接状态为已连接
      if (this.qpsConnectionStatus.value !== 'connected') {
        this.qpsConnectionStatus.value = 'connected'
        this.qpsReconnectAttempts = 0
      }
    } catch (error) {
      // 静默处理错误，避免控制台持续输出错误信息
      // 只在第一次失败或达到最大重试次数时输出错误
      if (this.qpsReconnectAttempts === 0) {
        console.warn('[QPS数据] 获取数据失败，将静默重试:', error)
      }
      this.qpsConnectionStatus.value = 'error'
      
      // 如果连续失败，尝试重连（静默重试，不输出日志）
      if (this.qpsReconnectAttempts < this.maxReconnectAttempts) {
        this.qpsReconnectAttempts++
        setTimeout(() => this.fetchQpsData(), this.reconnectDelay)
      } else if (this.qpsReconnectAttempts === this.maxReconnectAttempts) {
        // 只在达到最大重试次数时输出一次警告
        console.warn('[QPS数据] 获取数据失败，已达到最大重试次数，停止重试')
      }
    }
  }
  
  // 连接QPS曲线图（改为HTTP轮询方式）
  private async connectQpsChart() {
    // 如果已经在轮询，先停止
    if (this.qpsPollingInterval !== null) {
      this.disconnectQpsChart()
      await new Promise(resolve => setTimeout(resolve, 100))
    }
    
    this.qpsReconnectAttempts = 0
    this.qpsConnectionStatus.value = 'connecting'
    
    // 立即获取一次数据
    await this.fetchQpsData()
    
    // 设置定时轮询
    this.qpsPollingInterval = window.setInterval(() => {
      this.fetchQpsData()
    }, this.qpsPollingIntervalMs)
  }
  
  private disconnectQpsChart() {
    // 停止轮询
    if (this.qpsPollingInterval !== null) {
      clearInterval(this.qpsPollingInterval)
      this.qpsPollingInterval = null
    }
    this.qpsConnectionStatus.value = 'disconnected'
  }
  
  // 清空SSH日志
  public clearSSHLogs() {
    this.sshLogs.value = []
  }
  
  // 清空QPS数据（用于重新开始攻击时）
  public clearQpsData() {
    this.qpsData.dualStackQps = []
    this.qpsData.nonDualStackQps = []
    this.qpsData.maxQps = 100
    this.qpsData.analysisId = ''
    this.qpsStartTime = null
  }
  
  // 重置攻击包统计数据（用于重新开始攻击时）
  public resetPackageStats() {
    this.packageStats.totalPackages = 0
    this.packageStats.nonDualStackPackages = 0
    this.packageStats.timestamp = ''
    this.packageStats.victimTaskId = ''
    this.packageStats.attackDurationTime = 0
    this.packageStats.attackDuration = '0秒'
    this.packageStats.flashBobTime = 0
    console.log('[SSE管理器] 攻击包统计数据已重置')
  }
}

// 全局单例实例
let globalSSEManager: SSEConnectionManager | null = null

// 导出单例函数，确保全局只有一个实例
export function useSSEConnection() {
  if (!globalSSEManager) {
    globalSSEManager = new SSEConnectionManager()
  }
  
  return {
    sshLogs: globalSSEManager.sshLogs,
    packageStats: globalSSEManager.packageStats,
    qpsData: globalSSEManager.qpsData,
    sshConnectionStatus: globalSSEManager.getSshConnectionStatus(),
    qpsConnectionStatus: globalSSEManager.getQpsConnectionStatus(),
    clearSSHLogs: () => globalSSEManager!.clearSSHLogs(),
    clearQpsData: () => globalSSEManager!.clearQpsData(),
    resetPackageStats: () => globalSSEManager!.resetPackageStats(),
    startAllConnections: () => globalSSEManager!.startAllConnections(),
    stopAllConnections: () => globalSSEManager!.stopAllConnections()
  }
}

